<template>
  <div class="product-input-wrap">
    <!-- 查询条件 -->
    <el-card class="search-card mb16">
      <el-form :model="searchForm" inline label-width="100px">
        <el-form-item label="领料单号">
          <el-input
              v-model="searchForm.requisitionId"
              placeholder="请输入领料单号"
              clearable
              style="width: 200px;"
          />
        </el-form-item>

        <el-form-item label="入库日期">
          <el-date-picker
              v-model="searchForm.dateRange"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              clearable
              style="width: 300px;"
          />
        </el-form-item>

        <el-form-item label="入库状态">
          <el-select
              v-model="searchForm.status"
              placeholder="全部状态"
              clearable
              style="width: 180px;"
          >
            <el-option label="未审核入库" value="0" />
            <el-option label="已审核入库" value="1" />
          </el-select>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="handleSearch">查询</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 操作+分页 -->
    <el-row justify="space-between" align="middle" class="mb16">
      <el-button type="primary" :icon="Plus" @click="openAdd">+ 添加入库</el-button>
      <el-pagination
          background
          layout="total, prev, pager, next, jumper"
          :total="total"
          :page-size="size"
          v-model:current-page="page"
          @current-change="loadData"
      />
    </el-row>

    <!-- 表格 -->
    <el-card>
      <el-table
          :data="tableData"
          stripe
          v-loading="loading"
          :row-class-name="tableRowClassName"
          highlight-current-row
          style="width: 100%;"
          empty-text="暂无符合条件的入库数据"
      >
        <el-table-column label="ID" prop="id" width="80" align="center" />
        <el-table-column label="领料单号" prop="requisitionId" align="center" />
        <el-table-column prop="productId" label="商品名称" width="90">
          <template #default="{ row }">
            {{ getProOpts.find(i => i.value === row.productId)?.label || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="入库数量" prop="inputNum" align="center" />
        <el-table-column label="入库日期" prop="inputDate" align="center" />
        <el-table-column label="入库状态" align="center">
          <template #default="scope">
            <el-tag :type="statusColor(scope.row.status)">
              {{ statusMap[scope.row.status] }}
            </el-tag>
          </template>
        </el-table-column>

        <el-table-column label="操作" align="center" width="240" fixed="right">
          <template #default="scope">
            <template v-if="scope.row.status === 0">
              <el-button type="primary" size="small" @click="handleAudit(scope.row)">审核入库</el-button>
              <el-button type="info" size="small" @click="openEdit(scope.row)" style="margin-left: 8px;">编辑</el-button>
              <el-popconfirm title="确定删除该入库记录?" @confirm="handleDelete(scope.row.id)" confirm-button-text="确认" cancel-button-text="取消">
                <template #reference>
                  <el-button type="danger" size="small" style="margin-left: 8px;">删除</el-button>
                </template>
              </el-popconfirm>
            </template>
            <template v-else>
              <el-button type="warning" size="small" @click="handleUndoAudit(scope.row)">撤销审核</el-button>
            </template>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 新增/编辑抽屉 -->
    <el-drawer
        v-model="drawer"
        :title="isAdd ? '添加入库记录' : '编辑入库记录'"
        direction="rtl"
        size="600"
        destroy-on-close
        @opened="() => formRef = $refs.formRef"
        @closed="resetForm"
    >
      <el-form ref="formRef" :model="form" label-width="120px" class="add-form">
        <el-form-item label="领料单号" prop="requisitionId"
                      :rules="{ required: true, message: '请选择领料单号', trigger: 'change' }">
          <el-select
              v-model="form.requisitionId"
              placeholder="请选择领料单号"
              @change="handleRequisitionChange"
              clearable
          >
            <el-option
                v-for="item in requisitionList"
                :key="item.requisitionId"
                :label="item.requisitionId"
                :value="item.requisitionId"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="商品名称" prop="productName">
          <el-input v-model="form.productName" disabled />
        </el-form-item>

        <el-form-item label="仓库" prop="warehouseName">
          <el-input :modelValue="warehouseOpts.find(i=>i.value===form.warehouseId)?.label ?? ''" readonly />
        </el-form-item>

        <el-form-item label="入库数量" prop="inputNum"
                      :rules="{ required: true, message: '请输入入库数量', trigger: 'blur', type: 'number', min: 1 }">
          <el-input v-model.number="form.inputNum" />
        </el-form-item>

        <el-form-item label="计量单位" prop="unitName">
          <el-input :modelValue="unitOpts.find(i=>i.value===form.unitId)?.label ?? ''" readonly />
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="drawer = false">取消</el-button>
        <el-button type="primary" @click="submit">提交</el-button>
      </template>
    </el-drawer>

    <!-- 二维码弹窗 -->
    <el-dialog
        v-model="qrcodeDialogVisible"
        title="扫码入库"
        width="30%"
        :before-close="handleQrcodeDialogClose"
    >
      <div class="qrcode-container">
        <div id="qrcode" class="qrcode-img"></div>
        <p class="qrcode-desc">请扫描上方二维码完成入库审核</p>
      </div>
      <template #footer>
        <el-button @click="qrcodeDialogVisible = false">取消</el-button>
      </template>
    </el-dialog>

    <!-- 扫码确认弹窗 -->
    <el-dialog
        v-model="confirmDialogVisible"
        title="确认入库信息"
        width="50%"
    >
      <el-descriptions column="1" border>
        <el-descriptions-item label="领料单号">{{ currentInput.requisitionId }}</el-descriptions-item>
        <el-descriptions-item label="商品名称">{{ currentInput.productName }}</el-descriptions-item>
        <el-descriptions-item label="入库数量">{{ currentInput.inputNum }} {{ unitOpts.find(i=>i.value===currentInput.unitId)?.label }}</el-descriptions-item>
        <el-descriptions-item label="仓库">{{ warehouseOpts.find(i=>i.value===currentInput.warehouseId)?.label }}</el-descriptions-item>
        <el-descriptions-item label="创建时间">{{ dayjs(currentInput.createTime).format('YYYY-MM-DD HH:mm:ss') }}</el-descriptions-item>
      </el-descriptions>
      <template #footer>
        <el-button @click="confirmDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmStockIn">确认入库</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import dayjs from 'dayjs'
import isBetween from 'dayjs/plugin/isBetween'
import QRCode from 'qrcode'

import {
  findAllInput,
  addInput,
  updateInput,
  deleteInput,
  getRequisitionVo,
  getWarehouseOpts,
  getUnitOpts,
  scanStockIn,
  findByInputId,
  getProOpts
} from '../../api/wms.js'

dayjs.extend(isBetween)

const defaultForm = () => ({
  id: '',
  requisitionId: '',
  productName: '',
  warehouseName: '',
  inputNum: null,
  unitName: '',
  productId: null,
  warehouseId: null,
  unitId: null,
  employeeId: null,
  status: 0,
  createTime: null
})

export default {
  name: 'ProductInput',
  setup() {
    return { Plus }
  },
  data() {
    return {
      loading: false,
      tableData: [],
      total: 0,
      page: 1,
      size: 5,
      drawer: false,
      isAdd: true,
      form: defaultForm(),
      formRef: null,
      statusMap: { 0: '未审核入库', 1: '已审核入库' },
      requisitionList: [],
      unitOpts: [],
      warehouseOpts: [],
      searchForm: {
        requisitionId: '',
        dateRange: [],
        status: ''
      },
      qrcodeDialogVisible: false,
      confirmDialogVisible: false,
      currentInput: null,
      pollingTimer: null,
      getProOpts: []
    }
  },
  mounted() {
    this.loadSelect()
    this.loadData()
  },
  beforeUnmount() {
    if (this.pollingTimer) clearInterval(this.pollingTimer)
  },
  methods: {
    async loadSelect() {
      const [units, w, p] = await Promise.all([
        getUnitOpts(),
        getWarehouseOpts(),
        getProOpts()
      ])
      this.unitOpts = units
      this.warehouseOpts = w
      this.getProOpts = p || []
    },

    async loadData() {
      this.loading = true
      try {
        const res = await findAllInput()
        let list = []
        if (res.data.code === 200) {
          list = res.data.data.map(item => ({
            id: item.inputId,
            requisitionId: item.requisitionId,
            inputNum: item.num,
            inputDate: dayjs(item.createTime).format('YYYY-MM-DD'),
            status: item.status,
            productId: item.productId,
            warehouseId: item.warehouseId,
            unitId: item.unitId,
            employeeId: item.employeeId,
            createTime: item.createTime
          }))
        }

        if (this.searchForm.requisitionId) {
          list = list.filter(item =>
              item.requisitionId.toLowerCase().includes(this.searchForm.requisitionId.toLowerCase())
          )
        }
        if (this.searchForm.dateRange.length) {
          list = list.filter(item =>
              dayjs(item.inputDate).isBetween(
                  this.searchForm.dateRange[0],
                  this.searchForm.dateRange[1],
                  'day',
                  '[]'
              )
          )
        }
        if (this.searchForm.status !== '') {
          list = list.filter(item => item.status === Number(this.searchForm.status))
        }

        this.total = list.length
        this.tableData = list.slice((this.page - 1) * this.size, this.page * this.size)
      } catch (e) {
        ElMessage.error('获取数据失败：' + e.message)
      } finally {
        this.loading = false
      }
    },

    tableRowClassName({ row }) {
      return row.status === 0 ? 'warning-row' : 'success-row'
    },
    statusColor(status) {
      return status === 0 ? 'warning' : 'success'
    },

    openAdd() {
      this.isAdd = true
      this.resetForm()
      this.getRequisitionData()
      this.drawer = true
    },
    openEdit(row) {
      this.isAdd = false
      this.resetForm()
      const product = this.getProOpts.find(i => i.value === row.productId)
      this.form = {
        id: row.id,
        requisitionId: row.requisitionId,
        productId: row.productId,
        productName: product?.label || '',
        warehouseId: row.warehouseId,
        unitId: row.unitId,
        inputNum: row.inputNum,
        status: row.status,
        createTime: row.createTime
      }
      this.getRequisitionData()
      this.drawer = true
    },

    async handleDelete(id) {
      try {
        const res = await deleteInput(id)
        if (res.data.code === 200) {
          ElMessage.success('删除成功')
          this.loadData()
        } else {
          ElMessage.error('删除失败：' + res.data.msg)
        }
      } catch (e) {
        ElMessage.error('删除失败：' + e.message)
      }
    },

    async submit() {
      if (!this.$refs.formRef) return
      try {
        await this.$refs.formRef.validate()
        const submitData = {
          ...(this.isAdd ? {} : { inputId: this.form.id }),
          requisitionId: this.form.requisitionId,
          productId: this.form.productId,
          warehouseId: this.form.warehouseId,
          num: this.form.inputNum,
          unitId: this.form.unitId,
          employeeId: this.form.employeeId || 1,
          status: this.form.status ?? 0,
          createTime: this.isAdd ? new Date() : this.form.createTime
        }
        const api = this.isAdd ? addInput : updateInput
        const res = await api(submitData)
        if (res.data.code === 200) {
          ElMessage.success(this.isAdd ? '添加入库记录成功！' : '编辑入库记录成功！')
          this.drawer = false
          this.loadData()
        } else {
          ElMessage.error((this.isAdd ? '添加' : '编辑') + '失败：' + res.data.msg)
        }
      } catch (e) {
        if (e.name !== 'Error') return
        ElMessage.error('提交失败：' + e.message)
      }
    },

    resetForm() {
      this.form = defaultForm()
      this.requisitionList = []
      this.$nextTick(() => {
        if (this.$refs.formRef) this.$refs.formRef.resetFields()
      })
    },

    async getRequisitionData() {
      try {
        this.requisitionList = await getRequisitionVo()
      } catch (e) {
        ElMessage.error('获取领料单数据失败：' + e.message)
      }
    },

    handleRequisitionChange(requisitionId) {
      const selected = this.requisitionList.find(i => i.requisitionId === requisitionId)
      if (selected) {
        this.form.productName = selected.name || ''
        this.form.productId = selected.productId || null
        this.form.warehouseId = selected.warehouseId || null
        this.form.unitId = selected.unitId || null
        this.form.inputNum = selected.num || null
      } else {
        this.form.productName = ''
        this.form.productId = null
        this.form.warehouseId = null
        this.form.unitId = null
        this.form.inputNum = null
      }
    },

    // 扫码相关
    handleAudit(row) {
      this.currentInput = { ...row }
      this.qrcodeDialogVisible = true
      const qrUrl = `http://192.168.43.45:8080/mobile-confirm.html?inputId=${row.id}`
      QRCode.toDataURL(qrUrl, { width: 200, margin: 2 }).then(url => {
        const img = document.createElement('img')
        img.src = url
        document.getElementById('qrcode').innerHTML = ''
        document.getElementById('qrcode').appendChild(img)
      })
      this.startPolling(row.id)
    },
    startPolling(inputId) {
      this.pollingTimer = setInterval(async () => {
        const res = await findByInputId(inputId)
        if (res.data.code === 200 && res.data.data.status === 1) {
          ElMessage.success('入库已确认')
          this.qrcodeDialogVisible = false
          this.loadData()
          clearInterval(this.pollingTimer)
        }
      }, 2000)
    },
    handleQrcodeDialogClose() {
      this.qrcodeDialogVisible = false
      setTimeout(() => {
        this.confirmDialogVisible = true
      }, 3000)
    },
    async confirmStockIn() {
      if (!this.currentInput) return
      try {
        const res = await scanStockIn(this.currentInput.requisitionId)
        if (res.data.code === 200) {
          ElMessage.success('审核入库成功！')
          this.confirmDialogVisible = false
          this.qrcodeDialogVisible = false
          this.loadData()
        } else {
          ElMessage.error('审核入库失败：' + res.data.msg)
        }
      } catch (e) {
        ElMessage.error('审核入库失败：' + e.message)
      }
    },

    async handleUndoAudit(row) {
      try {
        const updateData = {
          inputId: row.id,
          productId: row.productId,
          employeeId: row.employeeId,
          num: row.inputNum,
          createTime: ' ',
          requisitionId: row.requisitionId,
          warehouseId: row.warehouseId,
          unitId: row.unitId,
          status: 0
        }
        const res = await updateInput(updateData)
        if (res.data.code === 200) {
          ElMessage.success('撤销审核成功！')
          this.loadData()
        } else {
          ElMessage.error('撤销审核失败：' + res.data.msg)
        }
      } catch (e) {
        ElMessage.error('撤销审核失败：' + e.message)
      }
    },

    handleSearch() {
      this.page = 1
      this.loadData()
    },
    resetSearch() {
      this.searchForm = {
        requisitionId: '',
        dateRange: [],
        status: ''
      }
      this.page = 1
      this.loadData()
    }
  }
}
</script>

<style scoped>
.product-input-wrap {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: calc(100vh - 60px);
}
.mb16 {
  margin-bottom: 16px;
}
.search-card {
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  border-radius: 8px;
  overflow: hidden;
}
::v-deep .el-form-item {
  margin-right: 16px;
  margin-bottom: 16px;
}
::v-deep .el-table .warning-row {
  --el-table-tr-bg-color: #fff8e6;
}
::v-deep .el-table .success-row {
  --el-table-tr-bg-color: #f0f9eb;
}
::v-deep .el-tag {
  padding: 4px 8px;
  font-size: 12px;
  border-radius: 4px;
}
.add-form {
  margin-top: 15px;
}
</style>